package sapling.service;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sapling.api.model.ApiAreaModel;
import sapling.api.model.ApiLandMassModel;
import sapling.api.model.ApiLandmass;
import sapling.dao.*;
import sapling.form.AreaForm;
import sapling.form.LandForm;
import sapling.model.*;
import sapling.utils.LetterUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Created by Administrator on 2017/6/21.
 */
@Service
@Transactional
public class AreaLocationService {

    @Autowired
    private LandMassDao landMassDao;
    @Autowired
    private AreaLocationDao areaLocationDao;
    @Autowired
    private AdminDao adminDao;
    @Autowired
    private TreeDao treeDao;
    @Autowired
    private TreeWellDao treeWellDao;
    @Autowired
    private LandMassService landMassService;

    /**
     * 查询所有已种植的地/空闲地块
     * @return
     */
    public List<ApiAreaModel> list(String treeSpecies){
        List<ApiAreaModel> apiAreaModels=new ArrayList<>();
        List<LandMass> landMasses= landMassDao.landMass(treeSpecies);
        for (LandMass value:landMasses) {
            ApiAreaModel apiAreaModel=new ApiAreaModel();
            apiAreaModel.setLandMass_id(value.getLandMass_id());
            apiAreaModel.setSerialNumber(value.getSerialNumber());
            apiAreaModel.setBreadth(value.getBreadth());
            apiAreaModel.setLength(value.getLength());
            apiAreaModel.setProportion(value.getProportion());
            apiAreaModel.setAreaLocation(value.getAreaLocation().getSerialNumber());
            apiAreaModels.add(apiAreaModel);
        }
        return apiAreaModels;
    }

    public List<ApiAreaModel> treeSpecies(int clump){
        List<ApiAreaModel> apiAreaModels=new ArrayList<>();
        List<LandMass> landMasses=landMassDao.landMassClump(clump);
        for (LandMass value:landMasses) {
            List<Tree> trees=treeDao.treesClump(clump,treeWellDao.landMassTreeWellId(value.getLandMass_id()));
            List<Tree> trees1=treeDao.findTreeSpeciesGroup(value.getLandMass_id());
            String treeSpecies="";
            for (Tree treevalue:trees1) {
                treeSpecies+=treevalue.getTreeSpecies()+";";
            }
            if(Objects.nonNull(trees)&&trees.size()>0){
                Tree tree=trees.get(0);
                ApiAreaModel apiAreaModel=new ApiAreaModel();
                apiAreaModel.setLandMass_id(value.getLandMass_id());
                apiAreaModel.setSerialNumber(value.getAreaLocation().getSerialNumber()+value.getSerialNumber());
                apiAreaModel.setQuantity(trees.size());
                apiAreaModel.setTreeSpecies(treeSpecies);
                apiAreaModel.setChestBreadth(tree.getChestBreadth());
                apiAreaModel.setHeight(tree.getHeight());
                apiAreaModel.setClump(tree.getClump());
                apiAreaModel.setSalenumber(tree.getSalenumber());
                if(Objects.nonNull(tree.getLandmassid())){
                    LandMass landMass=landMassDao.findOne(tree.getLandmassid());
                    apiAreaModel.setLength(landMass.getLength());
                    apiAreaModel.setBreadth(landMass.getBreadth());
                    apiAreaModel.setLandMassModels(landMassService.landplantinfo(tree.getLandmassid()));
                }
                apiAreaModels.add(apiAreaModel);
            }
        }
        return apiAreaModels;
    }

    public List<ApiAreaModel> serialNumber(String serialNumber){
        List<ApiAreaModel> apiAreaModels=new ArrayList<>();
        AreaLocation areaLocation=areaLocationDao.findbyname(serialNumber);
        if(Objects.nonNull(areaLocation)){
            List<LandMass> landMasses=areaLocation.getLandMasses();
            for (LandMass value:landMasses) {
                List<Tree> trees=treeDao.findBylandmass(value.getLandMass_id());
                List<Tree> trees1=treeDao.findTreeSpeciesGroup(value.getLandMass_id());
                String treeSpecies="";
                for (Tree treevalue:trees1) {
                    treeSpecies+=treevalue.getTreeSpecies()+";";
                }
                if(Objects.nonNull(trees)&&trees.size()>0){
                    ApiAreaModel apiAreaModel=new ApiAreaModel();
                    Tree tree=trees.get(0);
                    apiAreaModel.setLandMass_id(value.getLandMass_id());
                    apiAreaModel.setSerialNumber(value.getAreaLocation().getSerialNumber()+value.getSerialNumber());
                    apiAreaModel.setQuantity(trees.size());
                    apiAreaModel.setTreeSpecies(treeSpecies);
                    apiAreaModel.setChestBreadth(tree.getChestBreadth());
                    apiAreaModel.setHeight(tree.getHeight());
                    apiAreaModel.setClump(tree.getClump());
                    apiAreaModel.setSalenumber(tree.getSalenumber());
                    if(Objects.nonNull(tree.getLandmassid())){
                        LandMass landMass=landMassDao.findOne(tree.getLandmassid());
                        apiAreaModel.setLength(landMass.getLength());
                        apiAreaModel.setBreadth(landMass.getBreadth());
                        apiAreaModel.setLandMassModels(landMassService.landplantinfo(tree.getLandmassid()));
                        apiAreaModels.add(apiAreaModel);
                    }
                }
            }
        }
        return apiAreaModels;
    }

    public ApiAreaModel setland(LandMass value){
        List<Tree> trees=treeDao.findBylandmass(value.getLandMass_id());
        List<Tree> trees1=treeDao.findTreeSpeciesGroup(value.getLandMass_id());
        ApiAreaModel apiAreaModel=new ApiAreaModel();
        String treeSpecies="";
        for (Tree treevalue:trees1) {
            treeSpecies+=treevalue.getTreeSpecies()+";";
        }
        if(Objects.nonNull(trees)&&trees.size()>0){
            Tree tree=trees.get(0);
            apiAreaModel.setLandMass_id(value.getLandMass_id());
            apiAreaModel.setSerialNumber(value.getAreaLocation().getSerialNumber()+value.getSerialNumber());
            apiAreaModel.setQuantity(trees.size());
            apiAreaModel.setTreeSpecies(treeSpecies);
            apiAreaModel.setChestBreadth(tree.getChestBreadth());
            apiAreaModel.setHeight(tree.getHeight());
            apiAreaModel.setClump(tree.getClump());
            apiAreaModel.setSalenumber(tree.getSalenumber());
            if(Objects.nonNull(tree.getLandmassid())){
                LandMass landMass=landMassDao.findOne(tree.getLandmassid());
                apiAreaModel.setLength(landMass.getLength());
                apiAreaModel.setBreadth(landMass.getBreadth());
                apiAreaModel.setLandMassModels(landMassService.landplantinfo(tree.getLandmassid()));
            }
        }else{
            apiAreaModel.setLandMass_id(value.getLandMass_id());
            apiAreaModel.setSerialNumber(value.getAreaLocation().getSerialNumber()+value.getSerialNumber());
            apiAreaModel.setQuantity(trees.size());
            apiAreaModel.setTreeSpecies(treeSpecies);
            apiAreaModel.setChestBreadth(0);
            apiAreaModel.setHeight(0);
            apiAreaModel.setClump(false);
            apiAreaModel.setSalenumber(0);
            apiAreaModel.setLength(0);
            apiAreaModel.setBreadth(0);
            List<ApiLandMassModel> list=new ArrayList<>();
            ApiLandMassModel landMassModel=new ApiLandMassModel();
            landMassModel.setTreeWell_occupy(0);
            landMassModel.setTreeWell_quantity(0);
            list.add(landMassModel);
            apiAreaModel.setLandMassModels(list);
        }
        return apiAreaModel;
    }

    public List<ApiAreaModel> notTreeSpecies(String treeSpecies){
        List<ApiAreaModel> apiAreaModels=new ArrayList<>();
        List<LandMass> landMasses= landMassDao.notLandMass(treeSpecies);
        for (LandMass value:landMasses) {
            ApiAreaModel apiAreaModel=new ApiAreaModel();
            apiAreaModel.setLandMass_id(value.getLandMass_id());
            apiAreaModel.setSerialNumber(value.getSerialNumber());
            apiAreaModel.setBreadth(value.getBreadth());
            apiAreaModel.setLength(value.getLength());
            apiAreaModel.setProportion(value.getProportion());
            apiAreaModel.setAreaLocation(value.getAreaLocation().getSerialNumber());
            apiAreaModels.add(apiAreaModel);
        }
        return apiAreaModels;
    }


    public void add(AreaLocation area){
        Subject currentUser = SecurityUtils.getSubject();
        String username = currentUser.getSession().getAttribute("username").toString();
        Admin admin=adminDao.findOneByUsername(username);
        if(Objects.nonNull(admin)){
            AreaLocation areaLocation=new AreaLocation();
            areaLocation.setSerialNumber(area.getSerialNumber());
            areaLocation.setLength(area.getLength());
            areaLocation.setBreadth(area.getBreadth());
            areaLocation.setCompany(admin.getCompany());
            areaLocation.setProportion(area.getLength()*area.getBreadth());
            areaLocationDao.save(areaLocation);
        }
    }

    public void save(String areaArray,double areah,double areaw,double curveR,double carW,double curR){
        JSONArray json=JSONArray.fromObject(areaArray);
        JSONObject jsonOne;
        Subject currentUser = SecurityUtils.getSubject();
        String username = currentUser.getSession().getAttribute("username").toString();
        Admin admin=adminDao.findOneByUsername(username);
        AreaLocation areaLocation=new AreaLocation();
        areaLocation.setSerialNumber(LetterUtil.cutOut(areaLocationDao.number()));
        areaLocation.setBreadth(areaw);
        areaLocation.setLength(areah);
        areaLocation.setRoadBreadth(carW);
        areaLocation.setRadius(curveR);
        areaLocation.setCornerRadius(curR);
        areaLocation.setCompany(admin.getCompany());
        areaLocationDao.save(areaLocation);
        int number= 0;
        for(int i=0;i<json.size();i++){
            jsonOne = json.getJSONObject(i);
            LandMass landMass=new LandMass();
            landMass.setLength((Integer)jsonOne.get("h"));
            landMass.setBreadth((Integer)jsonOne.get("w"));
            landMass.setXcoordinate(Long.parseLong(""+jsonOne.get("x")));
            landMass.setYcoordinate(Long.parseLong(""+jsonOne.get("y")));
            landMass.setAreaLocation(areaLocation);
            landMass.setSerialNumber(++number+"");
            landMassDao.save(landMass);
        }
    }

    public void saveArea(List<AreaForm> areaForms) {
        for (AreaForm form : areaForms) {
            if (form.getW() == 0 || form.getH() == 0) {
                continue;
            }
            AreaLocation areaLocation = areaLocationDao.findbyname(form.getName());
            if (areaLocation == null) {
                areaLocation = new AreaLocation();
            }
            areaLocation.setSerialNumber(form.getName());
            areaLocation.setBreadth(form.getW());
            areaLocation.setLength(form.getH());
            areaLocation.setXpos(new Double(form.getX()).intValue());
            areaLocation.setYpos(new Double(form.getY()).intValue());
            areaLocationDao.saveAndFlush(areaLocation);
        }
    }
    public void saveLand(LandForm landForm) {
        List<AreaForm> areaForms=landForm.getAreaFormList();
        for (AreaForm form : areaForms) {
            if (form.getW() == 0 || form.getH() == 0) {
                continue;
            }
            LandMass landMass = landMassDao.findSerialNumber(landForm.getAreaid(),form.getName());
            if (landMass == null) {
                landMass = new LandMass();
            }
            landMass.setSerialNumber(form.getName());
            landMass.setBreadth(form.getW());
            landMass.setLength(form.getH());
            landMass.setXcoordinate(new Double(form.getX()).longValue());
            landMass.setYcoordinate(new Double(form.getY()).longValue());
            landMassDao.saveAndFlush(landMass);
        }
    }
    /**
     *删除区域
     * @param areaLocation_id
     */
    public void deleteArea(Long areaLocation_id){
        if(Objects.nonNull(areaLocation_id)){
            List<LandMass> landMassList = landMassDao.findArea(areaLocation_id);
            for (LandMass land:landMassList) {
                deleteLand(land.getLandMass_id());
            }
            areaLocationDao.delete(areaLocation_id);
        }
    }

    /**
     * 删除地块
     * @param landMass_id
     */
    public void deleteLand(Long landMass_id){
        if(Objects.nonNull(landMass_id)){
            List<TreeWell> treeWells = treeWellDao.getlandMassTreeWell(landMass_id);
            for(TreeWell treeWell:treeWells){
                deleteTreeWell(treeWell.getTreeWell_id());
            }
            landMassDao.delete(landMass_id);
        }
    }

    /**
     * 删除树坑
     */
    public void deleteTreeWell(Long treeWell_id){
        if(Objects.nonNull(treeWell_id)){
            TreeWell treeWell=treeWellDao.findOne(treeWell_id);
            if(Objects.nonNull(treeWell.getTree_id())){
               Tree tree= treeDao.findOne(treeWell.getTree_id());
                if(Objects.nonNull(tree)){
                    this.deleteTree(tree);
                }
            }
            treeWellDao.delete(treeWell_id);
        }
    }

    /**
     * 删除树
     */
    public void deleteTree(Tree tree){
        if(Objects.nonNull(tree)){
            treeDao.delete(tree);
        }
    }


    public ApiLandmass next(Long areaid){
        double space=4;//间距
        int minbreanch=5;
        int defbreach=18;
        int deflength=24;
        ApiLandmass apiLandmass=new ApiLandmass();
        AreaLocation areaLocation=areaLocationDao.findOne(areaid);
        if(Objects.nonNull(areaLocation)){
            apiLandmass.setAreaLocation_id(areaid);
            LandMass maxSerlandmass = landMassDao.findMaxSer(areaid);
            if(maxSerlandmass!=null) {
                apiLandmass.setSerialNumber((Integer.parseInt(maxSerlandmass.getSerialNumber()) + 1) + "");
                if (maxSerlandmass.getXcoordinate() + maxSerlandmass.getBreadth() + space + minbreanch <= areaLocation.getBreadth()) {
                    apiLandmass.setXcoordinate(maxSerlandmass.getXcoordinate() + maxSerlandmass.getBreadth() + space);
                    apiLandmass.setYcoordinate(maxSerlandmass.getYcoordinate());
                    apiLandmass.setLength(maxSerlandmass.getLength());
                    if (apiLandmass.getXcoordinate() + 18 <= areaLocation.getBreadth()) {
                        apiLandmass.setBreadth(18);
                    } else {
                        apiLandmass.setBreadth(areaLocation.getBreadth() - apiLandmass.getXcoordinate());
                    }
                } else {
                    LandMass maxYlandmass = landMassDao.findMaxYlandmass(areaid);
                    apiLandmass.setXcoordinate(0);
                    apiLandmass.setYcoordinate(maxYlandmass.getYcoordinate() + maxYlandmass.getLength());
                    if (deflength + apiLandmass.getYcoordinate() > areaLocation.getLength()) {
                        apiLandmass.setLength(areaLocation.getLength() - apiLandmass.getYcoordinate());
                    } else {
                        apiLandmass.setLength(deflength);
                    }
                    apiLandmass.setBreadth(defbreach);
                }
            }else{
                apiLandmass.setBreadth(defbreach);
                apiLandmass.setLength(deflength);
                apiLandmass.setXcoordinate(0);
                apiLandmass.setYcoordinate(0);
                apiLandmass.setSerialNumber(1+"");
                apiLandmass.setAreaLocation_id(areaid);
                apiLandmass.setSpace(space);
            }
        }
        return apiLandmass;
    }

    public void deleteAreabyname(String name) {
        AreaLocation area = areaLocationDao.findbyname(name);
        if(area!=null) {
            deleteArea(area.getAreaLocation_id());
        }
    }

    public void clearland(long landid) {
        if(Objects.nonNull(landid)){
            List<TreeWell> treeWells = treeWellDao.getlandMassTreeWell(landid);
            for(TreeWell treeWell:treeWells){
                deleteTreeWell(treeWell.getTreeWell_id());
            }
        }
    }
}
